package com.erlang.jpa.pojo;

import com.erlang.jpa.dao.CustomerDao;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

/**
 * 测试Specifications
 *
 * @Author ZGQ
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations="classpath:applicationContext.xml")
public class CustomerTestSpec {
  //依赖注入customerDao
  @Autowired
  private CustomerDao customerDao;

  /**
   * Specification接口中只定义了如下一个方法：
   *  root	：Root接口，代表查询的根对象，可以通过root获取实体中的属性
   *  query	：代表一个顶层查询对象，用来自定义查询
   *  cb		：用来构建查询，此对象里有很多条件方法
   * public Predicate toPredicate(Root<T> root, CriteriaQuery<?> query, CriteriaBuilder cb);
   */

  @Test
  public void testSpecifications() {
    //使用匿名内部类的方式，创建一个Specification的实现类，并实现toPredicate方法
    Specification<Customer> spec = new Specification<Customer>() {
      public Predicate toPredicate(Root<Customer> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
        //cb:构建查询，添加查询方式   like：模糊匹配
        //root：从实体Customer对象中按照custName属性进行查询
        return cb.like(root.get("custName").as(String.class), "阿丹%");
      }
    };
    Customer customer = customerDao.findOne(spec);
    System.out.println(customer);
  }

  /**
   * 构造分页参数
   * 		Pageable : 接口
   * 			PageRequest实现了Pageable接口，调用构造方法的形式构造
   * 				第一个参数：页码（从0开始）
   * 				第二个参数：每页查询条数
   *
   * 	分页查询，封装为Spring Data Jpa 内部的page bean
   * 		此重载的findAll方法为分页方法需要两个参数
   * 			第一个参数：查询条件Specification
   * 			第二个参数：分页参数
   */
  @Test
  public void testPage() {
    //构造查询条件
    Specification<Customer> spec = new Specification<Customer>() {
      public Predicate toPredicate(Root<Customer> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
        return cb.like(root.get("custName").as(String.class), "阿%");
      }
    };
    Pageable pageable = new PageRequest(0, 5);
    Page<Customer> page = customerDao.findAll(spec,pageable);

    page.getContent().forEach(System.out::println);
  }
}